/*******************************************************************************
  Application name: Voipaperi
  Filename: mainwindow.cpp
  Author: Juhapekka Piiroinen
  License: GNU/GPLv3
  Description:
      This is a quick-and-dirty application for layout analysis

  (C) 2010 Juhapekka Piiroinen
  http://code.google.com/p/quickanddirty
  juhapekka.piiroinen@gmail.com
*******************************************************************************/
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setAcceptDrops(true);
    setAutoFillBackground(true);
    //ui->labelBackground->setAutoFillBackground(true);
    //ui->graphicsView->setVisible(false);
    //ui->labelHelp->setVisible(false);
    ui->statusBar->showMessage("(C) 2010 Juhapekka Piiroinen - GNU/GPLv3 - http://code.google.com/p/voipaperi");

    this->setWindowTitle(QString("%0").arg(QCoreApplication::applicationName()));
    ui->graphicsView->setFocusPolicy(Qt::NoFocus); //disable keyboard and mouse event capture
}

void MainWindow::on_actionVoipaperi_mode_triggered() {
    IN;
        if (this->windowFlags().testFlag(Qt::SplashScreen)) {
            this->setWindowFlags(Qt::Window);

            ui->toolBar->setVisible(true);
            ui->statusBar->setVisible(true);
            this->setWindowOpacity(1.0);
            ui->graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
            ui->graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
        } else {
            ui->toolBar->setVisible(false);
            ui->statusBar->setVisible(false);
            this->setWindowFlags(Qt::SplashScreen);
            this->setWindowOpacity(0.5);
            ui->graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
            ui->graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        }
        this->show();

    OUT;
}

void MainWindow::on_actionHelp_triggered()
{
    this->showHelp();
}

void MainWindow::takeScreenshot()
{
    bool isCalledBySignal = (sender()!=NULL);
    QPixmap screenshot = QPixmap::grabWindow(QApplication::desktop()->winId());
    if (this->windowFlags().testFlag(Qt::SplashScreen)) {
        this->setWindowOpacity(0.5);
    }
    int width = this->width();
    int height = this->height();

    int x = this->pos().x();
    int y = this->pos().y();

    QPixmap croppedScreenshot = screenshot.copy(x,y,width,height);
    QString format = "png";

    if (isCalledBySignal) {
        QString fileName = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation) + tr("/voipaperi.%0.target.").arg(QDateTime::currentDateTime().toString("dd-MM-yyyy_hh-mm-ss")) + format;
        QString fileNameReference = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation) + tr("/voipaperi.%0.reference.").arg(QDateTime::currentDateTime().toString("dd-MM-yyyy_hh-mm-ss")) + format;
        qDebug() << fileName << fileNameReference;
        croppedScreenshot.save(fileName, format.toAscii());
        if (this->pixmap.isNull()==false) {
            this->pixmap.save(fileNameReference,format.toAscii());
        }
    } else {
        QString fileName = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation) + tr("/voipaperi.%0.combined.").arg(QDateTime::currentDateTime().toString("dd-MM-yyyy_hh-mm-ss")) + format;
        qDebug() << fileName;
        croppedScreenshot.save(fileName, format.toAscii());
    }
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    QApplication::exit();
}

void MainWindow::on_actionLoad_PNG_Layout_triggered()
{
    IN;
        QString filename = QFileDialog::getOpenFileName(this, tr("Open PNG Layout"),
                                                        QDesktopServices::storageLocation(QDesktopServices::DesktopLocation),
                                                         tr("PNG (*.png)"));
        if (filename.length()==0)
        {
            OUT;
            return;
        }
        qDebug() << filename;
        this->loadFromFile(filename);
    OUT;
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    QMainWindow::paintEvent(event);
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    IN;
        if (this->windowFlags().testFlag(Qt::SplashScreen))
        {
            if (event->key()==Qt::Key_F4) {
                on_actionVoipaperi_mode_triggered();
            } else if (event->key()==Qt::Key_F1) {
                showHelp();
            }
        }

    OUT;
}

void MainWindow::keyReleaseEvent(QKeyEvent *event)
{
    IN;


        if (event->key()==Qt::Key_F2) {
            takeScreenshot();
            if (this->windowFlags().testFlag(Qt::SplashScreen)) {
                this->setWindowOpacity(0);
            }
            QTimer::singleShot(500,this,SLOT(takeScreenshot()));
        } else if (event->key()==Qt::Key_F8) {
            if (this->windowOpacity()<1) {
                this->setWindowOpacity(1.0);
            } else {
                this->setWindowOpacity(0.5);
            }
        } else if (event->key()==Qt::Key_F9) {
            if (ui->graphicsView->scene()!=NULL) {
                QList<QGraphicsItem*> items = ui->graphicsView->scene()->items();
                foreach (QGraphicsItem* item, items) {
                    item->setFlag(QGraphicsItem::ItemIsMovable,!item->flags().testFlag(QGraphicsItem::ItemIsMovable));
                }
            }
        } else if (event->key()==Qt::Key_Right) {
            if (event->modifiers().testFlag(Qt::ShiftModifier)) {
                QSize siz = this->size();
                siz.setWidth(siz.width()+1);
                this->resize(siz);
            } else {
                QPoint pos = this->pos();
                pos.setX(pos.x()+1);
                this->move(pos);
            }
        } else if (event->key()==Qt::Key_Left) {
            if (event->modifiers().testFlag(Qt::ShiftModifier)) {
                QSize siz = this->size();
                siz.setWidth(siz.width()-1);
                this->resize(siz);
            } else {
                QPoint pos = this->pos();
                pos.setX(pos.x()-1);
                this->move(pos);
            }
        } else if (event->key()==Qt::Key_Up) {
            if (event->modifiers().testFlag(Qt::ShiftModifier)) {
                QSize siz = this->size();
                siz.setHeight(siz.height()-1);
                this->resize(siz);
            } else {
                QPoint pos = this->pos();
                pos.setY(pos.y()-1);
                this->move(pos);
            }
        } else if (event->key()==Qt::Key_Down) {
            if (event->modifiers().testFlag(Qt::ShiftModifier)) {
                QSize siz = this->size();
                siz.setHeight(siz.height()+1);
                this->resize(siz);
            } else {
                QPoint pos = this->pos();
                pos.setY(pos.y()+1);
                this->move(pos);
            }
        }
    OUT;
}

void MainWindow::showHelp()
{
    IN;
        QString help = "HELP:\n\n\nDrop a PNG file here.\n\nPress <ALT+F4> to close the application\n\nPress <F4> to toggle window style\n\nPress <F2> to take a screenshot.\n\nPress <F8> to toggle window Opacity\n\nUse <ARROW_KEY> to move window\n\nUse <SHIFT+ARROW_KEY> to resize window\n\nPress <F9> to move drop'd png file inside the window\n\nPress <F1> to toggle this help.";
        QMessageBox* msgbox = new QMessageBox(this);
        msgbox->setText(help);
        msgbox->exec();
        delete msgbox;
    OUT;
}

void MainWindow::dragLeaveEvent(QDragLeaveEvent *event)
{
    IN;
        event->accept();
    OUT;
}

void MainWindow::dragMoveEvent(QDragMoveEvent *event)
{
    IN;
        event->acceptProposedAction();
    OUT;
}

void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
    IN;
        event->acceptProposedAction();
    OUT;
}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    IN;
        QString msg = QString("X:%0 - Y:%1").arg(event->posF().x()).arg(event->posF().y());
        ui->statusBar->showMessage(msg);
    OUT;
}

MainWindow::~MainWindow()
{
    IN;
        delete ui;
    OUT;
}

void MainWindow::loadFromFile(QString filename)
{
    IN;
        if (ui->graphicsView->scene()==NULL) {
            ui->graphicsView->setScene(new QGraphicsScene());
        } else {
            ui->graphicsView->scene()->clear();
        }
        this->setWindowTitle(QString("%1 - %0").arg(QCoreApplication::applicationName()).arg(filename));
        QPixmap pix = QPixmap(filename);
        if (pix.isNull()==false) {
            this->pixmap = pix;
            qDebug() << "image set";
            QGraphicsPixmapItem* item = ui->graphicsView->scene()->addPixmap(pix);
            qDebug() << "image added";
            Q_UNUSED(item);
            //this->resize(pix.size());
        } else {
            qWarning() << "Image could not be loaded";
        }
    OUT;
}

void MainWindow::dropEvent(QDropEvent *event)
{
    IN;
        if (ui->graphicsView->scene()==NULL) {
            ui->graphicsView->setScene(new QGraphicsScene());
        } else {
            ui->graphicsView->scene()->clear();
        }
        const QMimeData *mimeData = event->mimeData();
        qDebug() << mimeData;

        if (mimeData->hasImage()) {
            qDebug() << "has image";
            QGraphicsPixmapItem* item = ui->graphicsView->scene()->addPixmap(qvariant_cast<QPixmap>(mimeData->imageData()));
            Q_UNUSED(item);
            //item->setFlag(QGraphicsItem::ItemIsMovable,true);
        } else {
            qDebug() << "has something else";
            QString filename = mimeData->urls().at(0).toLocalFile();
            loadFromFile(filename);
        }
    OUT;
}

void MainWindow::changeEvent(QEvent *e)
{
    IN;
        QMainWindow::changeEvent(e);
        switch (e->type()) {
        case QEvent::LanguageChange:
            ui->retranslateUi(this);
            break;
        default:
            break;
        }
    OUT;
}
